<!DOCTYPE html>
<html lang="zh_cn">
<head>
          <title>来玩魔王的咚</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta charset="utf-8" />
        <!-- twitter card metadata -->
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="/images/mowang.png">
<meta name="twitter:site" content="">
<meta name="twitter:title" content="Terraform 创建 Azure 虚拟机">
<meta name="twitter:description" content="<p>使用Terraform在Azure上创建虚拟机；销毁资源和状态文件；变量的声明、设置、引用、输出</p>">
        <!-- OG Tags -->
<meta property="og:url" content="/terraform-create-virtual-machine-on-azure.html"/>
<meta property="og:title" content="来玩魔王的咚 | Terraform 创建 Azure 虚拟机" />
<meta property="og:description" content="<p>使用Terraform在Azure上创建虚拟机；销毁资源和状态文件；变量的声明、设置、引用、输出</p>" />
        <!-- favicon -->
        <link rel="icon" type="image/png" href="/images/mowang.png">
        <!-- moment.js for date formatting -->
        <script src="/theme/js/moment.js"></script>
        <!-- css -->
        <link rel="stylesheet" type="text/css" href="/theme/css/main.css" />
        <!-- 左边的menu，如果页面高度不够，就跟着滚动，否则文章分类显示不全 -->
        <link rel="stylesheet" type="text/css" href="/theme/css/mycss/menu.css" />
		<script>
			
                /*! grunt-grunticon Stylesheet Loader - v2.1.2 | https://github.com/filamentgroup/grunticon | (c) 2015 Scott Jehl, Filament Group, Inc. | MIT license. */
    
    (function(e){function t(t,n,r,o){"use strict";function a(){for(var e,n=0;u.length>n;n++)u[n].href&&u[n].href.indexOf(t)>-1&&(e=!0);e?i.media=r||"all":setTimeout(a)}var i=e.document.createElement("link"),l=n||e.document.getElementsByTagName("script")[0],u=e.document.styleSheets;return i.rel="stylesheet",i.href=t,i.media="only x",i.onload=o||null,l.parentNode.insertBefore(i,l),a(),i}var n=function(r,o){"use strict";if(r&&3===r.length){var a=e.navigator,i=e.Image,l=!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect||!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")||e.opera&&-1===a.userAgent.indexOf("Chrome")||-1!==a.userAgent.indexOf("Series40")),u=new i;u.onerror=function(){n.method="png",n.href=r[2],t(r[2])},u.onload=function(){var e=1===u.width&&1===u.height,a=r[e&&l?0:e?1:2];n.method=e&&l?"svg":e?"datapng":"png",n.href=a,t(a,null,null,o)},u.src="",document.documentElement.className+=" grunticon"}};n.loadCSS=t,e.grunticon=n})(this);(function(e,t){"use strict";var n=t.document,r="grunticon:",o=function(e){if(n.attachEvent?"complete"===n.readyState:"loading"!==n.readyState)e();else{var t=!1;n.addEventListener("readystatechange",function(){t||(t=!0,e())},!1)}},a=function(e){return t.document.querySelector('link[href$="'+e+'"]')},c=function(e){var t,n,o,a,c,i,u={};if(t=e.sheet,!t)return u;n=t.cssRules?t.cssRules:t.rules;for(var l=0;n.length>l;l++)o=n[l].cssText,a=r+n[l].selectorText,c=o.split(");")[0].match(/US\-ASCII\,([^"']+)/),c&&c[1]&&(i=decodeURIComponent(c[1]),u[a]=i);return u},i=function(e){var t,o,a;o="data-grunticon-embed";for(var c in e)if(a=c.slice(r.length),t=n.querySelectorAll(a+"["+o+"]"),t.length)for(var i=0;t.length>i;i++)t[i].innerHTML=e[c],t[i].style.backgroundImage="none",t[i].removeAttribute(o);return t},u=function(t){"svg"===e.method&&o(function(){i(c(a(e.href))),"function"==typeof t&&t()})};e.embedIcons=i,e.getCSS=a,e.getIcons=c,e.ready=o,e.svgLoadedCallback=u,e.embedSVG=u})(grunticon,this);
                
                grunticon(["/theme/css/icons.data.svg.css", "/theme/css/icons.data.png.css", "/theme/css/icons.fallback.css"]);
            </script>
        <noscript><link href="/theme/css/icons.fallback.css" rel="stylesheet"></noscript>
        <!-- menu toggle javascript -->
        <script type="text/javascript">
            document.addEventListener("DOMContentLoaded", initMenu);
            
            function initMenu(){
                var menu = document.getElementById("menu");
                var menulink = document.getElementById("menu-link");
                menulink.addEventListener("click", function toggleMenu(){
                        window.event.preventDefault();
                        menulink.classList.toggle('active');
                        menu.classList.toggle('active');              
                    });
            };
        </script>
        <!-- 不蒜子 -->
        <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

    <meta name="description" content="<p>使用Terraform在Azure上创建虚拟机；销毁资源和状态文件；变量的声明、设置、引用、输出</p>" />

    <meta name="tags" content="terraform" />
    <meta name="tags" content="azure" />
  <!-- 替换部分base的样式，看文章时，要再宽一点，右边有很多空间可以撑开 -->
  <link rel="stylesheet" type="text/css" href="/theme/css/mycss/article.css" />

</head>
<body>
    <div role="banner" id="masthead">
        <header>
            <a href="/"><img src="/images/mowang.png" alt="McManus Logo"></a>
                <h1>来玩魔王的咚@骑士救兵</h1>
            <a href="#menu" id="menu-link">more stuff</a>
            <nav id="menu">
                <ul>
                        <li><a href="/tags">tags</a></li>
                            <li class="active"><a href="/category/cloud.html">Cloud</a></li>
                            <li><a href="/category/docker.html">Docker</a></li>
                            <li><a href="/category/go.html">Go</a></li>
                            <li><a href="/category/linux.html">Linux</a></li>
                            <li><a href="/category/python.html">Python</a></li>
                            <li><a href="/category/xue-xi-bi-ji.html">学习笔记</a></li>
                            <li><a href="/category/yun-wei-zi-dong-hua.html">运维自动化</a></li>
                </ul>
            </nav>
        </header>
    </div>
        <div class="page" role="main">
  <div class="article" role="article">
    <article>
        <footer>
            <a name="top"></a>
            <p>
              <time datetime=" 2021-05-06 10:00:00+08:00">
                <script>document.write(moment('2021-05-06 10:00:00+08:00').format('LL'));</script>
              </time>
              ~
              <time datetime=" 2021-05-06 10:00:00+08:00">
                <script>document.write(moment('2021-05-06 15:30:00+08:00').format('LL'));</script>
              </time>
            </p>
        </footer>
        <header>
          <h2>
            Terraform 创建 Azure 虚拟机
          </h2>
        </header>
      <div class="content">
         <div class="toc">
<ul>
<li><a href="#chuang-jian-xu-ni-ji-virtual-machine">创建虚拟机 virtual machine</a></li>
<li><a href="#xiao-hui-xu-ni-ji-dan-bao-liu-zi-yuan-zu">销毁虚拟机但保留资源组</a><ul>
<li><a href="#pei-zhi-wen-jian">配置文件</a></li>
<li><a href="#zhuang-tai-wen-jian">状态文件</a></li>
<li><a href="#zhi-xing-ji-hua">执行计划</a></li>
</ul>
</li>
<li><a href="#bian-liang-yin-yong">变量引用</a><ul>
<li><a href="#sheng-ming-bian-liang">声明变量</a></li>
<li><a href="#she-zhi-bian-liang">设置变量</a></li>
<li><a href="#yin-yong-bian-liang">引用变量</a></li>
<li><a href="#shu-chu-bian-liang">输出变量</a></li>
</ul>
</li>
<li><a href="#store-remote-state">Store Remote State</a></li>
</ul>
</div>
<p>资源属性查询：<br>
<a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group">https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group</a>  </p>
<p>Data Sources:<br>
<a href="https://www.terraform.io/docs/language/data-sources/index.html">https://www.terraform.io/docs/language/data-sources/index.html</a>  </p>
<h3 id="chuang-jian-xu-ni-ji-virtual-machine"><a class="toclink" href="#chuang-jian-xu-ni-ji-virtual-machine">创建虚拟机 virtual machine</a></h3>
<p><a href="https://learn.hashicorp.com/tutorials/terraform/azure-dependency?in=terraform/azure-get-started">https://learn.hashicorp.com/tutorials/terraform/azure-dependency?in=terraform/azure-get-started</a>  </p>
<p>Azure虚拟机部署前，依赖以下资源：  </p>
<ul>
<li>Resource group</li>
<li>Virtual network</li>
<li>Subnet</li>
<li>Network security group</li>
<li>Network interface</li>
</ul>
<p>下面是Azure上使用Terraform创建虚拟机的相关配置：</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Create a virtual network</span>
<span class="kr">resource</span><span class="w"> </span><span class="nc">&quot;azurerm_virtual_network&quot;</span><span class="w"> </span><span class="nv">&quot;vnet&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">name</span><span class="w">                </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFVnet&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">address_space</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;10.0.0.0/16&quot;</span><span class="p">]</span><span class="w"></span>
<span class="w">    </span><span class="na">location</span><span class="w">            </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;westus2&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">resource_group_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_resource_group.rg.name</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="kr">variable</span><span class="w"> </span><span class="nv">&quot;admin_username&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">string</span><span class="w"></span>
<span class="w">    </span><span class="na">description</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Administrator user name for virtual machine&quot;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="kr">variable</span><span class="w"> </span><span class="nv">&quot;admin_password&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">string</span><span class="w"></span>
<span class="w">    </span><span class="na">description</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Password must meet Azure complexity requirements&quot;</span><span class="w"></span>
<span class="p">}</span><span class="c1"></span>

<span class="c1"># Create subnet</span>
<span class="kr">resource</span><span class="w"> </span><span class="nc">&quot;azurerm_subnet&quot;</span><span class="w"> </span><span class="nv">&quot;subnet&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="na">name</span><span class="w">                 </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFSubnet&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">resource_group_name</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_resource_group.rg.name</span><span class="w"></span>
<span class="w">  </span><span class="na">virtual_network_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_virtual_network.vnet.name</span><span class="w"></span>
<span class="w">  </span><span class="na">address_prefixes</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;10.0.1.0/24&quot;</span><span class="p">]</span><span class="w"></span>
<span class="p">}</span><span class="c1"></span>

<span class="c1"># Create public IP</span>
<span class="kr">resource</span><span class="w"> </span><span class="nc">&quot;azurerm_public_ip&quot;</span><span class="w"> </span><span class="nv">&quot;publicip&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="na">name</span><span class="w">                </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFPublicIP&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">location</span><span class="w">            </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;westus2&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">resource_group_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_resource_group.rg.name</span><span class="w"></span>
<span class="w">  </span><span class="na">allocation_method</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Static&quot;</span><span class="w"></span>
<span class="p">}</span><span class="c1"></span>


<span class="c1"># Create Network Security Group and rule</span>
<span class="kr">resource</span><span class="w"> </span><span class="nc">&quot;azurerm_network_security_group&quot;</span><span class="w"> </span><span class="nv">&quot;nsg&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="na">name</span><span class="w">                </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFNSG&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">location</span><span class="w">            </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;westus2&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">resource_group_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_resource_group.rg.name</span><span class="w"></span>

<span class="w">  </span><span class="nb">security_rule</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">name</span><span class="w">                       </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;SSH&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">priority</span><span class="w">                   </span><span class="o">=</span><span class="w"> </span><span class="m">1001</span><span class="w"></span>
<span class="w">    </span><span class="na">direction</span><span class="w">                  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Inbound&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">access</span><span class="w">                     </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Allow&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">protocol</span><span class="w">                   </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Tcp&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">source_port_range</span><span class="w">          </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;*&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">destination_port_range</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;22&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">source_address_prefix</span><span class="w">      </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;*&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">destination_address_prefix</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;*&quot;</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="c1"></span>

<span class="c1"># Create network interface </span>
<span class="kr">resource</span><span class="w"> </span><span class="nc">&quot;azurerm_network_interface&quot;</span><span class="w"> </span><span class="nv">&quot;nic&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="na">name</span><span class="w">                      </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myNIC&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">location</span><span class="w">                  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;westus2&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">resource_group_name</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_resource_group.rg.name</span><span class="w"></span>

<span class="w">  </span><span class="nb">ip_configuration</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">name</span><span class="w">                          </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myNICConfg&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">subnet_id</span><span class="w">                     </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_subnet.subnet.id</span><span class="w"></span>
<span class="w">    </span><span class="na">private_ip_address_allocation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;dynamic&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">public_ip_address_id</span><span class="w">          </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_public_ip.publicip.id</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="c1"></span>

<span class="c1"># Create a Linux virtual machine</span>
<span class="kr">resource</span><span class="w"> </span><span class="nc">&quot;azurerm_virtual_machine&quot;</span><span class="w"> </span><span class="nv">&quot;vm&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="na">name</span><span class="w">                  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFVM&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">location</span><span class="w">              </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;westus2&quot;</span><span class="w"></span>
<span class="w">  </span><span class="na">resource_group_name</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_resource_group.rg.name</span><span class="w"></span>
<span class="w">  </span><span class="na">network_interface_ids</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="nv">azurerm_network_interface.nic.id</span><span class="p">]</span><span class="w"></span>
<span class="w">  </span><span class="na">vm_size</span><span class="w">               </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Standard_DS1_v2&quot;</span><span class="w"></span>

<span class="w">  </span><span class="nb">storage_os_disk</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">name</span><span class="w">              </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myOsDisk&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">caching</span><span class="w">           </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;ReadWrite&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">create_option</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;FromImage&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">managed_disk_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Premium_LRS&quot;</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>

<span class="w">  </span><span class="nb">storage_image_reference</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">publisher</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Canonical&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">offer</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;UbuntuServer&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">sku</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;18.04-LTS&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">version</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;latest&quot;</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>

<span class="w">  </span><span class="nb">os_profile</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">computer_name</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFVM&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">admin_username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">var.admin_username</span><span class="w"></span>
<span class="w">    </span><span class="na">admin_password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">var.admin_password</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>

<span class="w">  </span><span class="nb">os_profile_linux_config</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">disable_password_authentication</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">false</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="kr">data</span><span class="w"> </span><span class="nc">&quot;azurerm_public_ip&quot;</span><span class="w"> </span><span class="nv">&quot;ip&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="na">name</span><span class="w">                </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_public_ip.publicip.name</span><span class="w"></span>
<span class="w">  </span><span class="na">resource_group_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_virtual_machine.vm.resource_group_name</span><span class="w"></span>
<span class="w">  </span><span class="na">depends_on</span><span class="w">          </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="nv">azurerm_virtual_machine.vm</span><span class="p">]</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<h3 id="xiao-hui-xu-ni-ji-dan-bao-liu-zi-yuan-zu"><a class="toclink" href="#xiao-hui-xu-ni-ji-dan-bao-liu-zi-yuan-zu">销毁虚拟机但保留资源组</a></h3>
<p>销毁资源是根据状态文件terraform.tfstate中记录的资源进行删除的，而不是配置文件main.tf中的配置。<br>
要避免资源组被删除，注意一下几点：</p>
<ul>
<li>资源组不能在配置文件中，main.tf。避免资源记录到状态文件中。</li>
<li>资源组不能在状态文件中，terraform.tfstate。如果已经在状态文件中，需要去掉。</li>
<li>在yes确认前，仔细查看打印的执行计划，仔细检查是否包含<strong>azurerm_resource_group.rg</strong></li>
</ul>
<h4 id="pei-zhi-wen-jian"><a class="toclink" href="#pei-zhi-wen-jian">配置文件</a></h4>
<p>不把资源写进配置文件里，就不会创建该资源，状态文件中也不会记录。在销毁的时候也就不会删除这个资源。<br>
这需要在配置文件中直接使用已有的资源，而不是包含该资源的完整配置，然后引用该资源。<br>
下面是直接使用已有的资源组的配置示例：</p>
<div class="highlight"><pre><span></span><code><span class="kr">resource</span><span class="w"> </span><span class="nc">&quot;azurerm_public_ip&quot;</span><span class="w"> </span><span class="nv">&quot;publicip&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">name</span><span class="w">                </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFPublicIP&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">location</span><span class="w">            </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;westus2&quot;</span><span class="c1"></span>
<span class="c1">    #resource_group_name = azurerm_resource_group.rg.name</span>
<span class="w">    </span><span class="na">resource_group_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;资源组名称&quot;</span><span class="w"></span>
<span class="w">    </span><span class="na">allocation_method</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Static&quot;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>一个方法是直接写上名称（需要加上引号，否则会被认为是引用）。<br>
或者通过Data Sources从云端获取到资源的信息，然后再引用Data Sources的配置。  </p>
<h4 id="zhuang-tai-wen-jian"><a class="toclink" href="#zhuang-tai-wen-jian">状态文件</a></h4>
<p>从配置文件main.tf中删除掉某个资源的配置，这个逻辑应该是要删除掉对应的资源。也就是状态文件中有某个资源，但是配置文件中没有对应的资源，则执行plan时应该是删除这个资源。<br>
所以在执行destory的时候，不看资源是否在配置文件中，而是从状态文件中查找资源，然后删除状态文件中记录的这些资源。  </p>
<p>如果一开始资源组就不在配置文件中，那是没有问题的，因为状态文件中也不会有资源组。  </p>
<h5 id="cong-zhuang-tai-wen-jian-zhong-shan-chu-zi-yuan"><a class="toclink" href="#cong-zhuang-tai-wen-jian-zhong-shan-chu-zi-yuan">从状态文件中删除资源</a></h5>
<p>管理状态文件，使用terraform state系列的命令。可以使用rm来从状态文件中删除资源的信息：</p>
<div class="highlight"><pre><span></span><code>terraform state rm azurerm_resource_group.rg
</code></pre></div>

<p>删除前会自动备份状态文件。比如回生成一个<code>terraform.tfstate.1620277662.backup</code>的备份文件。最新的状态仍然记录在<code>terraform.tfstate</code>文件中。<br>
从备份中导入状态使用push命令：</p>
<div class="highlight"><pre><span></span><code>terraform state push terraform.tfstate.1620277662.backup 
</code></pre></div>

<h4 id="zhi-xing-ji-hua"><a class="toclink" href="#zhi-xing-ji-hua">执行计划</a></h4>
<p>在yes确认前，仔细核对执行计划，是最后的确认手段。之后资源的销毁是不可逆的操作。  </p>
<h3 id="bian-liang-yin-yong"><a class="toclink" href="#bian-liang-yin-yong">变量引用</a></h3>
<p>Define Input Variables：<br>
<a href="https://learn.hashicorp.com/tutorials/terraform/azure-variables?in=terraform/azure-get-started">https://learn.hashicorp.com/tutorials/terraform/azure-variables?in=terraform/azure-get-started</a>  </p>
<blockquote>
<p>不要重复自己（Don't Repeat Yourself,DRY）  </p>
</blockquote>
<p>在配置中定义变量，然后在每一个需要的位置引用变量。避免在一处进行了更改后，忘记了需要在另外一处进行相同的更改。<br>
这需要用到variable，用法示例如下：</p>
<div class="highlight"><pre><span></span><code><span class="c1"># 定义了变量，为提供值。执行命令后会通过交互的方式要求输入值</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;location&quot;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>

<span class="c1"># 有默认值，可以被替换的。未指定变量的值则使用默认值</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;prefix&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">type</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="n">string</span><span class="w"></span>
<span class="w">  </span><span class="n">default</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;my&quot;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1"># 这个变量是map类型</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;tags&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="w"></span>

<span class="w">  </span><span class="n">default</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Environment</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Terraform GS&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">Dept</span><span class="w">        </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Engineering&quot;</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1"># 这个也是map类型，缺省了对type的设置</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;sku&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">default</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">westus2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;16.04-LTS&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">eastus</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;18.04-LTS&quot;</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<h4 id="sheng-ming-bian-liang"><a class="toclink" href="#sheng-ming-bian-liang">声明变量</a></h4>
<p>声明变量的主题包含3个参数，都是可选的参数：  </p>
<ol>
<li>description: 描述，在查看源码，或运行plan、apply命令是都能看到这个描述信息。  </li>
<li>default: 命令行、属性文件、环境变量都可以为变量赋值，未赋值的时候，就使用default预定义的默认值。如果没有默认值，将通过交互提示用户输入值。  </li>
<li>type: 允许用户强制约束变量的类型，string、number、bool、map、set、object、tuple、any。如果未指定类型，默认类型为any。  </li>
</ol>
<p>更多的例子：</p>
<div class="highlight"><pre><span></span><code><span class="c1"># 这是一个列表的输入变量</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;list_example&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">description</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;An example of a list in Terraform&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">type</span><span class="w">        </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="w"></span>
<span class="w">    </span><span class="n">default</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;a&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;b&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;c&quot;</span><span class="p">]</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1"># 类型约束可以搭配使用，这里要求列表的元素是数字</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;list_numberic_example&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">description</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;An example of a numberic list in Terraform&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">type</span><span class="w">        </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">(</span><span class="n">number</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="n">default</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">]</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1"># 要求所有值均为字符串的映射对象</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;map_example&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">description</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;An example of a map in Terraform&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">type</span><span class="w">        </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="p">(</span><span class="n">string</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="n">default</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">key1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;value1&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">key2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;value2&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">key3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;value3&quot;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1"># 下面是一个复杂的对象的例子</span><span class="w"></span>
<span class="n">variable</span><span class="w"> </span><span class="s2">&quot;object_example&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">description</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;An example of a structural type in Terraform&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">type</span><span class="w">        </span><span class="o">=</span><span class="w"> </span><span class="n">object</span><span class="p">({</span><span class="w"></span>
<span class="w">        </span><span class="n">name</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="n">string</span><span class="w"></span>
<span class="w">        </span><span class="n">age</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="n">number</span><span class="w"></span>
<span class="w">        </span><span class="n">tags</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">(</span><span class="n">string</span><span class="p">)</span><span class="w"></span>
<span class="w">        </span><span class="n">enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb nb-Type">bool</span><span class="w"></span>
<span class="w">    </span><span class="p">})</span><span class="w"></span>
<span class="w">    </span><span class="n">default</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">name</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;value1&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">age</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="w"></span>
<span class="w">        </span><span class="n">tags</span><span class="w">    </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;a&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;b&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;c&quot;</span><span class="p">]</span><span class="w"></span>
<span class="w">        </span><span class="n">enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">true</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<h4 id="she-zhi-bian-liang"><a class="toclink" href="#she-zhi-bian-liang">设置变量</a></h4>
<p>有3种方式可以指定变量的值。  </p>
<h5 id="shi-yong-wen-jian"><a class="toclink" href="#shi-yong-wen-jian">使用文件</a></h5>
<p>文件要位于项目目录下，文件名可以是<code>terraform.tfvars</code> 或 <code>*.auto.tfvars</code>。<br>
在项目下创建<code>terraform.tfvars</code>文件，指定变量的值：</p>
<div class="highlight"><pre><span></span><code>location       = &quot;westus2&quot;
prefix         = &quot;tf&quot;
</code></pre></div>

<h5 id="ming-ling-xing"><a class="toclink" href="#ming-ling-xing">命令行</a></h5>
<p>在命令行中指定变量的值：</p>
<div class="highlight"><pre><span></span><code>terraform apply -var <span class="s1">&#39;location=westus2&#39;</span> -var <span class="s1">&#39;prefix=tf&#39;</span>
</code></pre></div>

<p>使用-var参数，并且可以多次使用，每次设置一个变量的值。  </p>
<h5 id="huan-jing-bian-liang"><a class="toclink" href="#huan-jing-bian-liang">环境变量</a></h5>
<p>环境变量的命名规范是<code>TF_&lt;name&gt;</code>。  </p>
<div class="highlight"><pre><span></span><code><span class="nb">export</span> <span class="nv">TF_location</span><span class="o">=</span><span class="s1">&#39;westus2&#39;</span>
</code></pre></div>

<h4 id="yin-yong-bian-liang"><a class="toclink" href="#yin-yong-bian-liang">引用变量</a></h4>
<p>通过变量来设置使用的端口：</p>
<div class="highlight"><pre><span></span><code><span class="n">variable</span><span class="w"> </span><span class="s2">&quot;ssh_port&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">desctiption</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;The port the server will use for SSH&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">type</span><span class="w">         </span><span class="o">=</span><span class="w"> </span><span class="n">number</span><span class="w"></span>
<span class="w">    </span><span class="n">default</span><span class="w">      </span><span class="o">=</span><span class="w"> </span><span class="mi">22</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="n">resource</span><span class="w"> </span><span class="s2">&quot;azurerm_network_security_group&quot;</span><span class="w"> </span><span class="s2">&quot;nsg&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">name</span><span class="w">                </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;myTFNSG&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">location</span><span class="w">            </span><span class="o">=</span><span class="w"> </span><span class="k">var</span><span class="o">.</span><span class="n">location</span><span class="w"></span>
<span class="w">    </span><span class="n">resource_group_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">azurerm_resource_group</span><span class="o">.</span><span class="n">rg</span><span class="o">.</span><span class="n">name</span><span class="w"></span>

<span class="w">    </span><span class="n">security_rule</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">name</span><span class="w">                       </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;SSH&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">priority</span><span class="w">                   </span><span class="o">=</span><span class="w"> </span><span class="mi">1001</span><span class="w"></span>
<span class="w">        </span><span class="n">direction</span><span class="w">                  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Inbound&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">access</span><span class="w">                     </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Allow&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">protocol</span><span class="w">                   </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Tcp&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">source_port_range</span><span class="w">          </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;*&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">destination_port_range</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="k">var</span><span class="o">.</span><span class="n">ssh_port</span><span class="w"></span>
<span class="w">        </span><span class="n">source_address_prefix</span><span class="w">      </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;*&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">destination_address_prefix</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;*&quot;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>关于map类型，假设需要根据虚拟机的区域来设定使用的os的版本：</p>
<div class="highlight"><pre><span></span><code><span class="n">variable</span><span class="w"> </span><span class="s2">&quot;sku&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">default</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">westus2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;16.04-LTS&quot;</span><span class="w"></span>
<span class="w">        </span><span class="n">eastus</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;18.04-LTS&quot;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="n">storage_image_reference</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">publisher</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Canonical&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">offer</span><span class="w">     </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;UbuntuServer&quot;</span><span class="w"></span>
<span class="w">    </span><span class="n">sku</span><span class="w">       </span><span class="o">=</span><span class="w"> </span><span class="n">lookup</span><span class="p">(</span><span class="k">var</span><span class="o">.</span><span class="n">sku</span><span class="p">,</span><span class="w"> </span><span class="k">var</span><span class="o">.</span><span class="n">location</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="n">version</span><span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;latest&quot;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>这里用了lookup函数，通过key来获取value的值。  </p>
<h4 id="shu-chu-bian-liang"><a class="toclink" href="#shu-chu-bian-liang">输出变量</a></h4>
<p>Terraform允许使用output来输出变量的值。包含两个可选参数：  </p>
<ol>
<li>description: 描述信息</li>
<li>senstitive: 敏感信息请设置该参数为true。这样不会在消息中输出。  </li>
</ol>
<p>可以将新创建的服务器的IP地址作为变量输出在命令行上：</p>
<div class="highlight"><pre><span></span><code><span class="c1"># 这个是Data Sources，获取资源的信息</span>
<span class="kr">data</span><span class="w"> </span><span class="nc">&quot;azurerm_public_ip&quot;</span><span class="w"> </span><span class="nv">&quot;ip&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">name</span><span class="w">                </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_public_ip.publicip.name</span><span class="w"></span>
<span class="w">    </span><span class="na">resource_group_name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nv">azurerm_virtual_machine.vm.resource_group_name</span><span class="w"></span>
<span class="w">    </span><span class="na">depends_on</span><span class="w">          </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="nv">azurerm_virtual_machine.vm</span><span class="p">]</span><span class="w"></span>
<span class="p">}</span><span class="c1"></span>

<span class="c1"># 输出服务器的IP地址</span>
<span class="kr">output</span><span class="w"> </span><span class="nv">&quot;public_ip_address&quot;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="na">value</span><span class="w">        </span><span class="o">=</span><span class="w"> </span><span class="nv">data.azurerm_public_ip.ip.ip_address</span><span class="w"></span>
<span class="w">    </span><span class="na">description</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;The public IP address of the VM&quot;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<h3 id="store-remote-state"><a class="toclink" href="#store-remote-state">Store Remote State</a></h3>
<p><a href="https://learn.hashicorp.com/tutorials/terraform/azure-remote?in=terraform/azure-get-started">https://learn.hashicorp.com/tutorials/terraform/azure-remote?in=terraform/azure-get-started</a><br>
共享状态，团队或多人协作是会需要，略。  </p>
      </div>
      <div class="back-to-top">
        <a href="/">HOME</a>
        <a href="#top">TOP</a>
      </div>
    </article>
  </div>
<!-- end article -->
<!-- 页面往下滚动一段之后才会显示TOC -->
<script>
  window.onscroll = function() {
    var tocbox = document.getElementsByClassName('toc')[0];
    var osTop = document.documentElement.scrollTop || document.body.scrollTop;
    var osWidth = document.documentElement.scrollWidth || document.body.scrollWidth;
    // console.log(osTop)
    if (osTop>300 && osWidth>865) {
      tocbox.style.display = "block"
    }
    if (osTop<300 || osWidth<865) {
      tocbox.style.display = "none"
    }
  }
</script>
                <footer>
                    <div class="icons">
                    </div>
                    <span id="busuanzi_container_page_pv" style="padding: 10px">本文阅读量<span id="busuanzi_value_page_pv"></span>次</span>
                    <span id="busuanzi_container_site_pv" style="padding: 10px">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
                    <span id="busuanzi_container_site_uv" style="padding: 10px">本站总访客数<span id="busuanzi_value_site_uv"></span>人</span>
                    <p>© <script>document.write(moment().format('YYYY'));</script> 749B</p>
                </footer>
        </div>
</body>
</html>